package com.xdap.table.service.impl;

import com.xdap.api.constant.ComponentType;
import com.xdap.api.constant.DateFormatConstant;
import com.xdap.api.moudle.formconfig.pojo.FormComponent;
import com.xdap.api.moudle.formconfig.pojo.XdapFormConfig;
import com.xdap.api.moudle.privateapaas.datamodel.pojo.ModelWithFieldVo;
import com.xdap.common.dao.InitFormDao;
import com.xdap.common.utils.ExcelUtil;
import com.xdap.common.utils.FormDataUtil;
import com.xdap.common.utils.InitDateFormatUtil;
import com.xdap.motor.utils.StringUtils;
import com.xdap.table.service.InitTableColumnService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class InitTableColumnServiceImpl implements InitTableColumnService {


    @Autowired
    private InitFormDao initFormDao;

    @Override
    public String init(String filePath, String formId) {
        if (!filePath.endsWith(".xlsx")) {
            filePath = filePath + "\\低代码表单字段类型-单sheet-" + InitDateFormatUtil.getCurrentYyyyMmDdHhMiSs() + ".xlsx";
        }
        // 创建文件对象
        File file = new File(filePath);

        OutputStream fos = null;
        XSSFWorkbook workbook = null;
        try {
            // 如果不存在，或者不是一个文件，直接新建一个响应的对象
            if (!file.exists() || !file.isFile()) {
                file.createNewFile();
            }

            fos = new FileOutputStream(file);
            workbook = new XSSFWorkbook();
            //
            List<XdapFormConfig> allEnableXdapFormConfig = null;
            if (StringUtils.isBlank(formId)) {
                allEnableXdapFormConfig = initFormDao.getAllEnableXdapFormConfig();
            } else {
                allEnableXdapFormConfig = new ArrayList<>();
                XdapFormConfig xdapFormConfig = initFormDao.getXdapFormConfig(formId);
                allEnableXdapFormConfig.add(xdapFormConfig);
            }
            initSheet(workbook, allEnableXdapFormConfig);


            workbook.write(fos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (workbook != null) {
                    workbook.close();
                    log.info("ExcelUtil.java ->> exportExcel() ->> 关闭Workbook资源");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            log.info("========================= ExcelUtil.java ->> exportExcel()导出数据到Excel中 ->> 结束 =========================");
        }

        return null;
    }


    private void initSheet(XSSFWorkbook workbook, List<XdapFormConfig> allEnableXdapFormConfig) {
        List<String> rowName = new ArrayList<>();
        rowName.add("页面名称");
        rowName.add("表名称");
        rowName.add("表编码");
        rowName.add("字段名称");
        rowName.add("字段编码");
        rowName.add("组件类型");
        rowName.add("默认参数");
        rowName.add("范围");

        List<List> dataList = new ArrayList<>();
        dataList.add(rowName);
        // 第一行数据，不需要做
        ExcelUtil.exportExcel(workbook, dataList, "页面字段一览", "", 0);

        for (XdapFormConfig xdapFormConfig : allEnableXdapFormConfig) {
            List<ModelWithFieldVo> modelWithFieldVoList = xdapFormConfig.getModelWithFieldVoList();
            String formName = xdapFormConfig.getFormName();
            // 一个页面做一次输入
            dataList = new ArrayList<>();

            // 获取关联表
            List<FormComponent> formComponents = xdapFormConfig.getDetailPage().getFormComponents();
            for (ModelWithFieldVo mw : modelWithFieldVoList) {
                List data = new ArrayList();

                // 命名主子表
                String modelCode = mw.getModelCode();
                String modelName = mw.getModelName();
                Boolean mainModel = mw.getMainModel();

          //      data.add(xdapFormConfig.getFormName());

                // 查询所有字段的fc，根据fc获取关联关系
                List<FormComponent> sonFc = FormDataUtil.getChildFc(formComponents);
                sonFc.addAll(formComponents);

                data.add(modelName);
                data.add(modelCode);
                // 获取页面上的字段名称字段编码等
                List<List> relTablesDetail = getRelTablesDetail(sonFc, modelCode, data, mainModel);
                if (CollectionUtils.isNotEmpty(relTablesDetail)) {
                    dataList.addAll(relTablesDetail);
                }
            }
            ExcelUtil.exportExcel(workbook, dataList, "页面字段一览", formName, 1);
        }


    }

    // 数值、地址、日期、手机号、电子邮箱、单据号
    private List<List> getRelTablesDetail(List<FormComponent> formComponents, String modelCode,
                                          List dataSource, Boolean mainModel) {
        List<List> dataList = new ArrayList<>();


        // 地址格式
        List<FormComponent> areaTables = formComponents.stream()
                .filter(fc -> ComponentType.FORM_WIDGET_AREA.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(areaTables)) {
            for (FormComponent fc : areaTables) {
                List<String> data = new ArrayList<>(dataSource);
//                data.add("xdap_province(地址表-xdap_manage_database数据库)");
//                data.add("xdap_province");
                String label = fc.getLabel();
                data.add(label);
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("地址");


                dataList.add(data);

            }
        }

//        // 单据号
//        List<FormComponent> docList = formComponents.stream()
//                .filter(fc -> ComponentType.FORM_DOCUMENT_NUMBER.equals(fc.getComponentType())
//                        && modelCode.equals(fc.getModelCode()))
//                .collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(docList)) {
//            for (FormComponent fc : docList) {
//                List<String> data = new ArrayList<>(dataSource);
//                // 字段名称
//                String label = fc.getLabel();
//                data.add(label);
//                // 字段编码
//                String modelField = fc.getModelField();
//                String[] split = modelField.split("\\.");
//                data.add(split[1]);
//                data.add("单据号");
//                dataList.add(data);
//            }
//        }

        // 超链接
        List<FormComponent> linkList = formComponents.stream()
                .filter(fc -> ComponentType.FORM_HYPERLINK_INPUT.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(linkList)) {
            for (FormComponent fc : linkList) {
                List<String> data = new ArrayList<>(dataSource);
                // 字段名称
                String label = fc.getLabel();
                data.add(label);
                // 字段编码
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("超链接");
                data.add(fc.getDefaultValue());
                dataList.add(data);
            }
        }

        // 电子邮箱
        List<FormComponent> emailList = formComponents.stream()
                .filter(fc -> ComponentType.FORM_EMAIL_INPUT.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(emailList)) {
            for (FormComponent fc : emailList) {
                List<String> data = new ArrayList<>(dataSource);
                // 字段名称
                String label = fc.getLabel();
                data.add(label);
                // 字段编码
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("电子邮箱");
                data.add(fc.getDefaultValue());
                dataList.add(data);
            }
        }
        // 手机号码
        List<FormComponent> phoneList = formComponents.stream()
                .filter(fc -> ComponentType.FORM_PHONE_INPUT.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(phoneList)) {
            for (FormComponent fc : phoneList) {
                List<String> data = new ArrayList<>(dataSource);
                // 字段名称
                String label = fc.getLabel();
                data.add(label);
                // 字段编码
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("手机号码");
                data.add(fc.getDefaultValue());
                dataList.add(data);
            }
        }
        // 证件号
        List<FormComponent> cardList = formComponents.stream()
                .filter(fc -> ComponentType.FORM_IDCARD_INPUT.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(cardList)) {
            for (FormComponent fc : cardList) {
                List<String> data = new ArrayList<>(dataSource);
                // 字段名称
                String label = fc.getLabel();
                data.add(label);
                // 字段编码
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("证件号");
                data.add(fc.getDefaultValue());
                dataList.add(data);
            }
        }
        // 数字
        List<FormComponent> numList = formComponents.stream()
                .filter(fc -> ComponentType.FORM_NUMBER_INPUT.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(numList)) {
            for (FormComponent fc : numList) {
                List<String> data = new ArrayList<>(dataSource);
                // 字段名称
                String label = fc.getLabel();
                data.add(label);
                // 字段编码
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("数字");
                data.add(fc.getDefaultValue());
                Double numberMax = fc.getNumberMax();
                Double numberMin = fc.getNumberMin();

                // 获取小数点位之后，计算double值，预留小数
                Integer decimalNum = fc.getDecimalNum();
                data.add(double2Str(numberMin, decimalNum) + "~" + double2Str(numberMax, decimalNum));
                dataList.add(data);
            }
        }

        // 金额
        List<FormComponent> moneyList = formComponents.stream()
                .filter(fc -> ComponentType.FORM_MONEY_INPUT.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(moneyList)) {
            for (FormComponent fc : moneyList) {
                List<String> data = new ArrayList<>(dataSource);
                // 字段名称
                String label = fc.getLabel();
                data.add(label);
                // 字段编码
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("金额");
                data.add(fc.getDefaultValue());
                Double numberMax = fc.getNumberMax();
                Double numberMin = fc.getNumberMin();

                // 获取小数点位之后，计算double值，预留小数
                Integer decimalNum = fc.getDecimalNum();
                data.add(double2Str(numberMin, decimalNum) + "~" + double2Str(numberMax, decimalNum));
                dataList.add(data);
            }
        }


        // 日期
        List<FormComponent> dateList = formComponents.stream()
                .filter(fc -> ComponentType.FORM_DATEPICK_INPUT.equals(fc.getComponentType())
                        && modelCode.equals(fc.getModelCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(dateList)) {
            for (FormComponent fc : dateList) {
                List<String> data = new ArrayList<>(dataSource);
                // 字段名称
                String label = fc.getLabel();
                data.add(label);
                // 字段编码
                String modelField = fc.getModelField();
                String[] split = modelField.split("\\.");
                data.add(split[1]);
                data.add("日期");
                data.add(fc.getDefaultValue());
                String dateDisplayStyle = fc.getDateDisplayStyle();
                if(StringUtils.isNotBlank(dateDisplayStyle)){
                    switch (dateDisplayStyle) {
                        case DateFormatConstant.ONLY_YEAR:
                            data.add("输入年");
                            break;
                        case DateFormatConstant.DATE_TIME:
                            data.add("输入年月日时间");
                            break;
                        case DateFormatConstant.ONLY_DATE:
                            data.add("输入日期");
                            break;
                        case DateFormatConstant.YEAR_MONTH:
                            data.add("输入年月");
                            break;
                        default:
                            break;
                    }
                }


                dataList.add(data);
            }
        }

        return dataList;
    }


    private String double2Str(Double number, Integer decimalNum) {
        String str = "";
        if(number == null){
            return str;
        }

        if (decimalNum == null || decimalNum == 0) {

            str = number.intValue() + "";
        } else {
            str = String.format("%." + decimalNum + "f", number);

        }

        return str;
    }
}
